/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SLE_THING_MODEL_DEFINE_H
#define SLE_THING_MODEL_DEFINE_H

#include <stdlib.h>
#include <string>
#include <stdbool.h>
#include <functional>
#include <unordered_map>
#include "iotc_event.h"
#include "iotc_oh_sdk.h"
#include "iotc_oh_device.h"
#include "securec.h"
#include "iotc_log.h"
#include "parameter.h"
#include "util.h"

namespace OHOS{
namespace iotConnect {
static const int32_t THING_MODEL_DEFAULT_SERVICE_NUMBER = 10;
static const int32_t STATION_CONTROLLER_DEFAULT_SERVICE_NUMBER = 9;
static const int32_t LEAKER_DETECTOR_DEFAULT_SERVICE_NUMBER = 9;
static const int32_t CONTROL_VALUE_DEFAULT_SERVICE_NUMBER = 9;

// struct SvcMap {
//     const char *devTypeId;
//     const IotcServiceInfo *svc;
//     int32_t (*putCharState)(const IotcServiceInfo *svc, const char *data, uint32_t len);
//     int32_t (*getCharState)(const IotcServiceInfo *svc, char **data, uint32_t *len);
// };

enum PeerConnectType{
    PEER_CONNECT_TYPE_ONLINE = 0, /* online */
    PERR_CONNECT_TYPE_OFFLINE = 1 /* offline */
};

struct SleBaseDeviceInfo{
    std::string brand = ""; /* brand */
    std::string deviceId = ""; /* device id */
    std::string serialNumber = ""; /* serial number */
    PeerConnectType peerConnectStatus = PERR_CONNECT_TYPE_OFFLINE; /* connect status */
}; /* Device information */

struct SleBaseEthInfo{
    std::string ethMac = ""; /* Ethernet MAC address */
    std::string ipv4Addr = ""; /* IPv4 address */
    std::string ipv6Addr = ""; /* IPv6 address */
}; /* Ethernet network information */

struct SleBaseWiFiInfo{
    std::string wifiMac = ""; /* WiFi MAC address */
    std::string ipv4Addr = ""; /* IPv4 address */
    std::string ipv6Addr = ""; /* IPv6 address */
    int RSSI = -140; /* RSSI
                        min:-140
                        max:30
                        step:1
                        unit:dbm */
    std::string SSID = ""; /* SSID name */
}; /* Wi-Fi network information */

struct SleBaseBtInfo{
    std::string btMac = ""; /* Bluetooth MAC address */
    int RSSI = -140; /* RSSI
                        min:-140
                        max:30
                        step:1
                        unit:dbm */
}; /* Bluetooth network information */

struct SleBaseSleInfo{
    std::string sleMac = ""; /* Sle MAC address */
    int RSSI = -140; /* RSSI
                        min:-140
                        max:30
                        step:1
                        unit:dbm */
}; /* Sle network information */

enum DiscoveryType{
    DISCOVERY_TYPE_BLE = 0,
    DISCOVERY_TYPE_SLE = 1,
    DISCOVERY_TYPE_NFC = 2,
    DISCOVERY_TYPE_SCAN_THE_CODE = 3,
    DISCOVERY_TYPE_COAP = 4,
    DISCOVERY_TYPE_COMBO = 5,
    DISCOVERY_TYPE_RESERVED = 6
};

enum AccessType{
    ACCESS_TYPE_SLE = 0,
    ACCESS_TYPE_IP = 1, /* WLAN/Ethernet/4G/5G */
};

struct ConfigurationManagementInfo{
    DiscoveryType discoveryType = DISCOVERY_TYPE_RESERVED; /* Discovery Type */
    AccessType accessType = ACCESS_TYPE_SLE; /* Access Type */
    std::string deviceName = ""; /* Device Name */
}; /* Configuration Management */

struct SleBaseCPUInfo{
    std::string manufacturer = ""; /* Manufacturer */
    std::string model = ""; /* Model */
    uint8_t currentUsage; /* Current usage */
    uint8_t usageThreshold; /* Usage threshold */
}; /* CPU information */

enum OSType{
    OS_TYPE_STANDARD = 0,
    OS_TYPE_SMALL = 1,
    OS_TYPE_MINI = 2
};

struct SleBaseOSInfo{
    std::string version = ""; /* os version */
    OSType type = OS_TYPE_STANDARD; /* os type */
}; /* OS information */

enum OTAActionType{
    /* 0-Check version */
    OTA_ACTION_TYPE_CHECK_VERSION = 0,
    /* 1-Start upgrade */
    OTA_ACTION_TYPE_START_UPGRADE = 1,
    /* 2-Start upgrade without restart */
    OTA_ACTION_TYPE_START_UPGRADE_WITHOUT_RESTART = 2,
    /* 3-Restart */
    OTA_ACTION_TYPE_RESTART = 3,
};

enum UpgradeCode{
    /* 100-Success */
    UPGRADE_CODE_SUCCESS = 100,
    /* 1000-Failed, network except */
    UPGRADE_CODE_FAILED_NETWORK_EXCEPT = 1000,
    /* 1001-Failed, firmware download failed */
    UPGRADE_CODE_FAILED_FIRMWARE_DOWNLOAD = 1001,
    /* 1002-Failed, firmware check failed */
    UPGRADE_CODE_FAILED_FIRMWARE_CHECK = 1002,
};

struct SleBaseOTAInfo{
    OTAActionType action = OTA_ACTION_TYPE_CHECK_VERSION;
    uint16_t bootTime = 1;/* Bootime
                            min:1
                            max:3600
                            step:1
                            unit:S */
    std::string introduction = "";
    uint8_t progress = 0;/* Progress
                            min:0
                            max:100
                            step:1
                            unit:% */
    std::string version = "";
    std::string url = "";
    bool on = false;/* Upgrade on or off
                       0-Disable upgrade
                       1-Enable upgrade */
    UpgradeCode code = UPGRADE_CODE_SUCCESS;
};

struct SleBaseRestartInfo{
    bool restart = true; /* Restart
                            0-Restart
                            1-Sleep */
};

struct SleBaseFactoryReset{
    bool resetAllSettings = true; /* 1-Reset All Settings */
};

enum LeakDetectorIndicateStatus{
    /* 0-Normal (Green led is on) */
    INDICATE_STATUS_NORMAL = 0,
    /* 1-Gas Leaks (Red led flick) */
    INDICATE_STATUS_GAS_LEAKS = 1,
    /* 2-Device work Abnormally (Yellow led flick) */
    INDICATE_STATUS_LEAKER_DETECTOR_DEVICE_WOEK_ABNORMALLY = 2,
};

struct LeakDetectorServiceList{
    uint32_t gasLeakEscalationValue = 0; /* Gas Leak Escalation Value
                                            min:0
                                            max:0xFFFFFFFF
                                            step:1
                                            unit:cm^3 */
    LeakDetectorIndicateStatus statusIndicator = INDICATE_STATUS_NORMAL; /* Status Indicator */
};

enum ControlValueGasValueGear{
    /* 0-Low Speed */
    GAS_CALUE_GEAR_LOW_SPEED = 0,
    /* 1-Medium Speed */
    GAS_CALUE_GEAR_MEDIUM_SPEED = 1,
    /* 2-High Speed */
    GAS_CALUE_GEAR_HIGH_SPEED = 2,
};

enum ControlValueIndicateStatus{
    /* 0-Execution Succeed(Green led flick 3 seconds) */
    INDICATE_STATUS_EXECUTION_SUCCEED = 0,
    /* 1-Execution Failed (Red led flick 3 seconds) */
    INDICATE_STATUS_EXECUTION_FAILED = 1,
    /* 2-Device work abnormally (Yellow led flick) */
    INDICATE_STATUS_CONTROL_VALUE_DEVICE_WOEK_ABNORMALLY = 2,
};

struct ControlValueServiceList{
    bool gasValveSwitch; /* The Gas Valve Switch*/
    ControlValueGasValueGear gears = GAS_CALUE_GEAR_LOW_SPEED; /* Gas Valve Gear */
    /* Status Indicator */
    ControlValueIndicateStatus statusIndicator = INDICATE_STATUS_EXECUTION_SUCCEED;
};

enum SubThingModelExecResult {
    SUB_MODEL_FAIL = -1,
    SUB_MODEL_SUCC = 0,
    SUB_MODEL_TIMEOUT,
};

typedef struct {
    uint64_t msgSeq;
    std::string msgId;
    std::string devId;
    std::string svcId;
    timer_t timerId;
    std::function<void(const SubThingModelExecResult res, const std::string& msgId, const std::string& svcId,
        const std::string& devId, const char *data, const uint32_t len)> onResult;
} MessageTimerAttr;

enum class SvcType : char {
    DEV_INFO,
    WIFI_INFO,
    SLE_INFO,
    CONFIGURATION_MAG,
    CPU,
    OS,
    OTA,
    RESTART,
    FACTORY_RESET,
    SERVICE_LIST,
    GET_SN,
};

enum class ThingModelPutOrGet : char {
    GET,
    PUT,
};

static std::unordered_map<std::string, SvcType> mapThingModelSvcStation
{
    {"devInfo", SvcType::DEV_INFO},
    {"wifiInfo", SvcType::WIFI_INFO},
    {"sleInfo", SvcType::SLE_INFO},
    {"configurationManagement", SvcType::CONFIGURATION_MAG},
    {"cpu", SvcType::CPU},
    {"os", SvcType::OS},
    {"ota", SvcType::OTA},
    {"restart", SvcType::RESTART},
    {"factoryReset", SvcType::FACTORY_RESET},
    {"snw", SvcType::GET_SN},
};

static std::unordered_map<std::string, SvcType> mapThingModelSvcLeaker
{
    {"devInfo", SvcType::DEV_INFO},
    {"sleInfo", SvcType::SLE_INFO},
    {"serviceList", SvcType::SERVICE_LIST},
    {"configurationManagement", SvcType::CONFIGURATION_MAG},
    {"cpu", SvcType::CPU},
    {"os", SvcType::OS},
    {"ota", SvcType::OTA},
    {"restart", SvcType::RESTART},
    {"factoryReset", SvcType::FACTORY_RESET},
};


static std::unordered_map<std::string, SvcType> mapThingModelSvcControl
{
    {"devInfo", SvcType::DEV_INFO},
    {"sleInfo", SvcType::SLE_INFO},
    {"serviceList", SvcType::SERVICE_LIST},
    {"configurationManagement", SvcType::CONFIGURATION_MAG},
    {"cpu", SvcType::CPU},
    {"os", SvcType::OS},
    {"ota", SvcType::OTA},
    {"restart", SvcType::RESTART},
    {"factoryReset", SvcType::FACTORY_RESET},
};

}
}
#endif
